package com.wumz.netty.tomcat.nio;

import com.wumz.netty.tomcat.nio.handler.AbstractTomcatHandler;
import com.wumz.netty.tomcat.nio.http.MyServlet;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.sctp.nio.NioSctpServerChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;

import java.io.FileInputStream;
import java.net.ServerSocket;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

/**
 * Created by wumz on 2021/2/5 16:54
 */
public class MyTomcat {

    private int port = 8080;

    private int workThread = 4;

    private Properties properties = new Properties();

    private Map<String, MyServlet> servletMapping = new HashMap<>();

    public static void main(String[] args) {
        new MyTomcat().start();
    }

    //Tomcat启动入口
    private void start() {
        //1、加载web-nio.properties配置文件
        init();

        //boss线程
        NioEventLoopGroup boss = new NioEventLoopGroup(1);
        //work线程
        NioEventLoopGroup work = new NioEventLoopGroup(workThread);

        //创建Netty服务端对象
        ServerBootstrap bootstrap = new ServerBootstrap();

        try {
            //配置服务端参数
            bootstrap.group(boss,work)
                    .channel(NioServerSocketChannel.class)
                    .childHandler(new AbstractTomcatHandler(servletMapping))
                    .option(ChannelOption.SO_BACKLOG, 128)
                    .childOption(ChannelOption.SO_KEEPALIVE, true);

            //启动服务
            ChannelFuture future = bootstrap.bind(this.port).sync();
            System.out.println("Tomcat 已启动，监听端口是: " + this.port);
            future.channel().closeFuture().sync();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            work.shutdownGracefully();
            boss.shutdownGracefully();
        }
    }

    private void init() {
        try {
            //加载配置
            String path = this.getClass().getResource("/").getPath();
            FileInputStream inputStream = new FileInputStream(path + "web-nio.properties");
            properties.load(inputStream);
            //遍历
            for (Object obj : properties.keySet()){
                String key = obj.toString();
                // .url结尾的，拼接的URL和Servlet建立映射关系
                if (key.endsWith(".url")){
                    //将 servlet.xxx.url 的 .url 替换，只剩下 servlet.xxx当成  servletName
                    String servletName = key.replaceAll("\\.url$", "");
                    String url = properties.getProperty(key);
                    //拿到servlet全类名
                    String clazz = properties.getProperty(servletName + ".className");
                    //反射创建Servlet的实例
                    MyServlet servlet = (MyServlet)Class.forName(clazz).newInstance();
                    //URL和Servlet建立映射关系
                    servletMapping.put(url,servlet);
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}
